package com.member.mp.web;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.member.common.core.domain.R;
import com.member.common.enums.EnableStatusEnum;
import com.member.common.enums.OrderDeleteEnum;
import com.member.common.utils.StringUtils;
import com.member.mp.web.user.SupperController;
import com.member.shop.domain.*;
import com.member.shop.dto.OperateDto;
import com.member.shop.service.*;
import com.member.shop.vo.CartCountVo;
import com.member.shop.vo.CartVo;
import com.member.shop.vo.GoodsEntity;
import com.member.system.cache.CommonCache;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 【购物车】控制器
 *
 * @author wangxin
 * @version 1.0
 * @date Mon Jul 03 22:06:51 CST 2024
 **/
@Slf4j
@Api(value = "购物车接口", tags = {"购物车接口"})
@RestController
@RequestMapping("/wx/cart")
public class CartController extends SupperController {

    public static final String CART_KEY = "CART:";

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ISysBizGoodsSkuService sysBizGoodsSkuService;
    @Resource
    private ISysBizGoodsService sysBizGoodsService;
    @Resource
    private ISysBizOrderService sysBizOrderService;
    @Resource
    private ISysBizOrderGoodsService sysBizOrderGoodsService;
    @Resource
    private ISysBizUserService sysBizUserService;

    private String getCartKey() {
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();

        String key = CART_KEY + tenantId + ":" + userId;
        return key;
    }

    /**
     * 查询购物车统计数量（返回 商品总数 与总件数）
     *
     * @return
     */
    @GetMapping("/queryCartCountByUser")
    public R<CartCountVo> queryCartCountByUser() {
        String key = getCartKey();
        CartCountVo cartVo = new CartCountVo();
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
        SysBizUser sysBizUser = sysBizUserService.selectSysBizUserById(getUserId());
        // 获取所有的购物车数据
        List<Object> cartList = cartMap.values();
        int i = 0;
        BigDecimal amount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(cartList)) {
            List<GoodsEntity> items = new ArrayList<>();

            for (Object item : cartList) {
                String objStr = (String) item;
                GoodsEntity goodVo = JSON.parseObject(objStr, GoodsEntity.class);
                // 查询价格
                SysBizGoodsSku sysBizGoodsSku = sysBizGoodsSkuService.selectSysBizGoodsSkuByGoodsIdAndKey(goodVo.getGoodsId(), goodVo.getSpecsKey());
                if (goodVo == null) {
                    continue;
                }
                if (sysBizGoodsSku == null) {
                    continue;
                }

                // 如果标签不为空就用活动价格
                if(sysBizGoodsSku.getTag() != null){

                    goodVo.setSalesPrice(sysBizGoodsSku.getActivityPrice());

                }else if (sysBizUser != null) {               // 根据身份等级设置商品价格
                    if (sysBizUser.getMemberGradeId() == 1) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip1Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 2) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip2Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 3) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip3Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 4) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip4Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 5) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip5Price());
                    }
                }

                goodVo.setLimitNumber(sysBizGoodsSku.getLimitNumber());
                goodVo.setLongUnit(sysBizGoodsSku.getLongUnit());
                goodVo.setUnit(sysBizGoodsSku.getUnit());
                goodVo.setUnitNumber(sysBizGoodsSku.getUnitNumber());
                goodVo.setLongUnitNumber(sysBizGoodsSku.getLongUnitNumber());
                goodVo.setMarketPrice(sysBizGoodsSku.getMemberMarketPrice());

                goodVo.setIsEnable(Boolean.TRUE);
                SysBizGoods byId = sysBizGoodsService.getById(goodVo.getGoodsId());
                goodVo.setStock(byId.getStock() - byId.getFrozenStockCount());
                if (Objects.equals(sysBizGoodsSku.getStatus(), EnableStatusEnum.NO_ENABLE.getKey())
                        || byId == null || byId.getGrounding() == 1
                        || Objects.equals(byId.getDeleted(), OrderDeleteEnum.DELETE.getKey())
                        || byId.getStock() - byId.getFrozenStockCount() <= 0
                        || byId.getStock() - byId.getFrozenStockCount() < goodVo.getNumber() * goodVo.getLongUnitNumber()) {
                    goodVo.setIsEnable(Boolean.FALSE);
                }
                items.add(goodVo);
                i += Integer.parseInt(goodVo.getNumber().toString());
                amount = amount.add(goodVo.getSalesPrice().multiply(BigDecimal.valueOf(goodVo.getNumber())));
            }
            cartVo.setGoodsNum(items.size());
            cartVo.setTotalNum(i);
            cartVo.setTotalPrice(amount);

        }
        return R.ok(cartVo);
    }

    /**
     * 查询用户购物车
     *
     * @return
     */
    @GetMapping("/queryCartByUser")
    public R<CartVo> queryCartByUser() {
        String key = getCartKey();
        CartVo cartVo = new CartVo();
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
        SysBizUser sysBizUser = sysBizUserService.selectSysBizUserById(getUserId());
        // 获取所有的购物车数据
        List<Object> cartList = cartMap.values();
        int i = 0;
        BigDecimal amount = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(cartList)) {
            List<GoodsEntity> items = new ArrayList<>();

            for (Object item : cartList) {
                String objStr = (String) item;
                GoodsEntity goodVo = JSON.parseObject(objStr, GoodsEntity.class);
                // 查询价格
                SysBizGoodsSku sysBizGoodsSku = sysBizGoodsSkuService.selectSysBizGoodsSkuByGoodsIdAndKey(goodVo.getGoodsId(), goodVo.getSpecsKey());
                if (goodVo == null) {
                    continue;
                }
                if (sysBizGoodsSku == null) {
                    continue;
                }

                // 如果标签不为空就用活动价格
                if(sysBizGoodsSku.getTag() != null){

                    goodVo.setSalesPrice(sysBizGoodsSku.getActivityPrice());

                }else if (sysBizUser != null) {               // 根据身份等级设置商品价格
                    if (sysBizUser.getMemberGradeId() == 1) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip1Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 2) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip2Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 3) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip3Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 4) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip4Price());
                    }
                    if (sysBizUser.getMemberGradeId() == 5) {
                        goodVo.setSalesPrice(sysBizGoodsSku.getVip5Price());
                    }
                }
                goodVo.setSkuId(sysBizGoodsSku.getId());
                goodVo.setLimitNumber(sysBizGoodsSku.getLimitNumber());
                goodVo.setLongUnit(sysBizGoodsSku.getLongUnit());
                goodVo.setUnit(sysBizGoodsSku.getLongUnit());
                goodVo.setUnitNumber(sysBizGoodsSku.getUnitNumber());
                goodVo.setLongUnitNumber(sysBizGoodsSku.getLongUnitNumber());
                goodVo.setMarketPrice(sysBizGoodsSku.getMemberMarketPrice());


                goodVo.setIsEnable(Boolean.TRUE);
                SysBizGoods byId = sysBizGoodsService.getById(goodVo.getGoodsId());
                goodVo.setStock(byId.getStock() - byId.getFrozenStockCount());
                if (Objects.equals(sysBizGoodsSku.getStatus(), EnableStatusEnum.NO_ENABLE.getKey())
                        || byId == null || byId.getGrounding() == 1
                        || Objects.equals(byId.getDeleted(), OrderDeleteEnum.DELETE.getKey())
                        || byId.getStock() - byId.getFrozenStockCount() <= 0
                        || byId.getStock() - byId.getFrozenStockCount() < goodVo.getNumber() * goodVo.getLongUnitNumber()) {
                    goodVo.setIsEnable(Boolean.FALSE);
                }
                items.add(goodVo);
                i += Integer.parseInt(goodVo.getNumber().toString());
                amount = amount.add(goodVo.getSalesPrice().multiply(BigDecimal.valueOf(goodVo.getNumber())));
            }
            //最近添加排前面
            items.sort(Comparator.comparing(GoodsEntity::getAddTime, Comparator.reverseOrder()));
            cartVo.setTotalNum(i);
            cartVo.setGoodsNum(items.size());
            cartVo.setTotalPrice(amount);
            cartVo.setGoodsEntityList(items);
        }
        return R.ok(cartVo);
    }

    /**
     * 添加用户购物车
     *
     * @param operateDto 参数
     * @return
     */
    @PostMapping("/addCart")
    public R<String> addCart(@RequestBody @Validated OperateDto operateDto) {
        // 用户购物车存储的key
        String key = getCartKey();
        // 获取用户购物车数据
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);

        String configValue = CommonCache.getConfigValue("sys.cart.limit.number");
        int limitNumber = 100;
        try {
            if (StringUtils.isNotEmpty(configValue)) {
                limitNumber = Integer.parseInt(configValue);
            }
        } catch (Exception e) {

        }

        int size = cartMap.entries().size();
        if (size >= limitNumber) {
            log.info(key + ":超出最大数量，" + size);
            return R.ok("购物车已达上限，请删除其他商品再添加");
        }
        // 判断商品是否存在
        String cart = (String) cartMap.get(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey());
        if (StringUtils.isBlank(cart)) {
            // 商品不存在,则添加商品信息
            SysBizGoodsSku sysBizGoodsSku = sysBizGoodsSkuService.selectSysBizGoodsSkuByGoodsIdAndKey(operateDto.getGoodsId(), operateDto.getSpecsKey());
            GoodsEntity goodVo = new GoodsEntity();
            goodVo.setSpecsKey(operateDto.getSpecsKey());
            goodVo.setSpecsData(sysBizGoodsSku.getSpecsData());
//            goodVo.setPrice(sysBizGoodsSku.getSalesPrice());
            goodVo.setLimitNumber(sysBizGoodsSku.getLimitNumber());
            goodVo.setLongUnit(sysBizGoodsSku.getLongUnit());
            goodVo.setUnit(sysBizGoodsSku.getUnit());
            goodVo.setUnitNumber(sysBizGoodsSku.getUnitNumber());
            goodVo.setLongUnitNumber(sysBizGoodsSku.getLongUnitNumber());
            goodVo.setNumber(operateDto.getNum());
            goodVo.setAddTime(LocalDateTime.now());
            goodVo.setModifyTime(LocalDateTime.now());
            goodVo.setSkuPic(sysBizGoodsSku.getPic());
            goodVo.setGoodsId(sysBizGoodsSku.getGoodsId());
//            SysBizGoods sysBizGoods = sysBizGoodsService.getById(sysBizGoodsSku.getGoodsId());
            goodVo.setGoodsName(sysBizGoodsSku.getSkuName());
            cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(goodVo));
            return R.ok();
        }
        // 商品存在,则数量增加
        GoodsEntity item = JSON.parseObject(cart, GoodsEntity.class);
        if (item.getAddTime() == null) {
            item.setAddTime(LocalDateTime.now());
        }
        item.setModifyTime(LocalDateTime.now());
        long total = item.getNumber() + operateDto.getNum();
        item.setNumber(total);
        cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(item));
        return R.ok();
    }

    /**
     * 修改用户购物车（不修改选中状态）
     *
     * @param operateDto 参数
     * @return
     */
    @PostMapping("/updateCart")
    public R<String> updateCart(@RequestBody @Validated OperateDto operateDto) {
        log.info("修改购物车商品");
        // 用户购物车存储的key
        String key = getCartKey();
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
        String cart = (String) cartMap.get(operateDto.getGoodsId() + "_" + operateDto.getSpecsKeyOld());
        GoodsEntity item = JSON.parseObject(cart, GoodsEntity.class);
        if (StringUtils.isNotNull(item)) {
            item.setNumber(operateDto.getNum());
            item.setSpecsKey(operateDto.getSpecsKey());
            SysBizGoodsSku sysBizGoodsSku = sysBizGoodsSkuService.selectSysBizGoodsSkuByGoodsIdAndKey(operateDto.getGoodsId(), operateDto.getSpecsKey());
            item.setSpecsData(sysBizGoodsSku.getSpecsData());
            item.setSkuPic(sysBizGoodsSku.getPic());


            item.setLimitNumber(sysBizGoodsSku.getLimitNumber());
            item.setLongUnit(sysBizGoodsSku.getLongUnit());
            item.setUnit(sysBizGoodsSku.getUnit());
            item.setUnitNumber(sysBizGoodsSku.getUnitNumber());
            item.setLongUnitNumber(sysBizGoodsSku.getLongUnitNumber());
            cartMap.delete(operateDto.getGoodsId() + "_" + operateDto.getSpecsKeyOld());
            cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(item));
            return R.ok();
        }
        return R.fail("未找到商品sku");
    }

    /**
     * 批量选中与取消购物车中商品（这里只能全选可选商品，所有要传现有购物车中商品信息）
     *
     * @param operateDtos 参数
     * @return
     */
    @PostMapping("/select")
    public R<String> select(@RequestBody List<OperateDto> operateDtos) {
        log.info("修改购物车商品");
        // 用户购物车存储的key
        String key = getCartKey();
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
        for (OperateDto operateDto : operateDtos) {
            String cart = (String) cartMap.get(operateDto.getGoodsId() + "_" + operateDto.getSpecsKeyOld());
            GoodsEntity item = JSON.parseObject(cart, GoodsEntity.class);
            if (StringUtils.isNotNull(item)) {

                item.setSelect(operateDto.isSelect());

                cartMap.delete(operateDto.getGoodsId() + "_" + operateDto.getSpecsKeyOld());
                cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(item));

            }

        }
        return R.ok();

    }

    /**
     * 删除用户购物车
     *
     * @param operateDto 参数（传specsKey和goodsId）
     * @return
     */
    @PostMapping("/deleteCart")
    public R<String> deleteCart(@RequestBody List<OperateDto> operateDto) {
        log.info("删除购物车商品");
        String key = getCartKey();
        // 用户购物车存储的key
        for (OperateDto operateVo : operateDto) {

            BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
            cartMap.delete(operateVo.getGoodsId() + "_" + operateVo.getSpecsKey());
        }
        return R.ok();
    }

    /**
     * 再来一单
     * @param id 订单id
     * @return 成功or失败
     */
    @PostMapping("/oneMoreOrder")
    public R<String> oneMoreOrder(@RequestParam("id") Long id) {
        SysBizOrder sysBizOrder = sysBizOrderService.getById(id);
        if (sysBizOrder == null) {
            return R.fail("订单不存在");
        }
        // 订单状态 待支付：10、已支付：15、待发货：20、已发货：30、已完成：40、已取消：90、售后中: 80、售后成功：85、售后失败：88
        if(sysBizOrder.getStatus() != 15 && sysBizOrder.getStatus() != 20 && sysBizOrder.getStatus() != 40 && sysBizOrder.getStatus() != 90){
            return R.fail("订单状态异常,无法再来一单");
        }
        List<SysBizOrderGoods> goodsList = sysBizOrderGoodsService.selectSysBizOrderGoodsList(new LambdaQueryWrapper<SysBizOrderGoods>()
                .eq(SysBizOrderGoods::getOrderId, sysBizOrder.getId()));

        List<OperateDto> operateDtoList = new ArrayList<>();
        goodsList.forEach(g->{
            OperateDto dto = new OperateDto();
            dto.setGoodsId(g.getGoodsId());
            dto.setSpecsKey(g.getSpecsKey());
            dto.setNum(g.getNumber());
            operateDtoList.add(dto);
        });

        // 用户购物车存储的key
        String key = getCartKey();
        // 获取用户购物车数据
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);

        String configValue = CommonCache.getConfigValue("sys.cart.limit.number");
        int limitNumber = 100;
        try {
            if (StringUtils.isNotEmpty(configValue)) {
                limitNumber = Integer.parseInt(configValue);
            }
        } catch (Exception e) {

        }

        int size = cartMap.entries().size();
        if (size >= limitNumber) {
            log.info(key + ":超出最大数量，" + size);
            return R.fail("购物车已达上限，请删除其他商品再添加");
        }

        operateDtoList.stream().forEach(operateDto -> {
            // 判断商品是否存在
            String cart = (String) cartMap.get(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey());
            if (StringUtils.isBlank(cart)) {
                // 商品不存在,则添加商品信息
                SysBizGoodsSku sysBizGoodsSku = sysBizGoodsSkuService.selectSysBizGoodsSkuByGoodsIdAndKey(operateDto.getGoodsId(), operateDto.getSpecsKey());
                GoodsEntity goodVo = new GoodsEntity();
                goodVo.setSpecsKey(operateDto.getSpecsKey());
                goodVo.setSpecsData(sysBizGoodsSku.getSpecsData());
                goodVo.setLimitNumber(sysBizGoodsSku.getLimitNumber());
                goodVo.setLongUnit(sysBizGoodsSku.getLongUnit());
                goodVo.setUnit(sysBizGoodsSku.getUnit());
                goodVo.setUnitNumber(sysBizGoodsSku.getUnitNumber());
                goodVo.setLongUnitNumber(sysBizGoodsSku.getLongUnitNumber());
                goodVo.setNumber(operateDto.getNum());
                goodVo.setAddTime(LocalDateTime.now());
                goodVo.setModifyTime(LocalDateTime.now());
                goodVo.setSkuPic(sysBizGoodsSku.getPic());
                goodVo.setGoodsId(sysBizGoodsSku.getGoodsId());
//                SysBizGoods sysBizGoods = sysBizGoodsService.getById(sysBizGoodsSku.getGoodsId());
                goodVo.setGoodsName(sysBizGoodsSku.getSkuName());
                cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(goodVo));
            } else {
                // 商品存在,则数量增加
                GoodsEntity item = JSON.parseObject(cart, GoodsEntity.class);
                if (item.getAddTime() == null) {
                    item.setAddTime(LocalDateTime.now());
                }
                item.setModifyTime(LocalDateTime.now());
                long total = item.getNumber() + operateDto.getNum();
                item.setNumber(total);
                cartMap.put(operateDto.getGoodsId() + "_" + operateDto.getSpecsKey(), JSON.toJSONString(item));
            }
        });

        return R.ok();
    }
}
